package com.example.ymm.modules1.service.impl.ms;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.example.ymm.base.BaseServiceImpl;
import com.example.ymm.bo.YmUserDetails;
import com.example.ymm.model.TableList;
import com.example.ymm.model.UserLogin;
import com.example.ymm.model.YmPageDto;
import com.example.ymm.modules1.entity.ms.MsOrderItemView;
import com.example.ymm.modules1.entity.ms.VckStock;
import com.example.ymm.modules1.entity.my.sys.iot.IotMsLog;
import com.example.ymm.modules1.entity.my.sys.iot.IotTag;
import com.example.ymm.modules1.entity.my.sys.iot.IotTimeLog;
import com.example.ymm.modules1.mapper.ms.MsOrderItemViewMapper;
import com.example.ymm.modules1.query.ms.MsOrderItemViewQueryCriteria;
import com.example.ymm.modules1.query.sys.iot.IotTagQueryCriteria;
import com.example.ymm.modules1.service.dd.iot.IotHttpUtil;
import com.example.ymm.modules1.service.dto.ms.FnMsLocationDto;
import com.example.ymm.modules1.service.dto.ms.ListenerOutOrderItemDto;
import com.example.ymm.modules1.service.dto.ms.ListenerStockItemDto;
import com.example.ymm.modules1.service.ms.MsOrderItemViewService;
import com.example.ymm.modules1.service.sys.iot.IotMsLogService;
import com.example.ymm.modules1.service.sys.iot.IotTagService;
import com.example.ymm.modules1.service.sys.iot.IotTimeLogService;
import com.example.ymm.util.*;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.stream.Collectors;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
@DS("slave2")
public class MsOrderItemViewServiceImpl extends BaseServiceImpl<MsOrderItemViewMapper, MsOrderItemView> implements MsOrderItemViewService {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    IotTagService iotTagService;
    @Autowired
    IotHttpUtil iotHttpUtil;
    @Value("${spring.profiles.active}")
    String PD_MATCH;
    @Autowired
    IotMsLogService iotMsLogService;
    @Autowired
    IotTimeLogService iotTimeLogService;


    @Override
    public TableList<MsOrderItemView> list(MsOrderItemViewQueryCriteria criteria, YmPageDto pageDto) {
//        IPage<MsOrderItemView> page = new Page<MsOrderItemView>(pageDto.getPage(),pageDto.getPageSize());
        String deptIds="11,98";
        List<String> deptIdIn = Arrays.asList(deptIds.split(","));
        criteria.setSalesmanDeptIdIn(deptIdIn);
//        QueryWrapper predicate = QueryHelpPlus.getPredicate(SysApprovalSettingLine.class, criteria);
//        predicate.orderByDesc("create_time");
//        baseMapper.selectPage(page, predicate);
//        TableList<MsOrderItemView> tableList=new TableList(page);
        getPage(pageDto);
        List<MsOrderItemView> orderList = orderItemList(criteria);
        PageInfo<MsOrderItemView> pageInfo = new PageInfo<>(orderList);
        TableList<MsOrderItemView> tableList=new TableList(pageInfo);
        return tableList;
    }

    @Override
    public List<MsOrderItemView> orderItemList(MsOrderItemViewQueryCriteria criteria) {
        return baseMapper.orderItemList(criteria);
    }

    @Override
    public String createLoginToken() {
        UserLogin userLogin=new UserLogin();
        //    userLogin.setPlatform(EmLoginPlatform.pc_3.getType());
        userLogin.setId("sjj-api");
        userLogin.setPassword("Kp@7Gm$2Rt%9Qw&5Jh#3Nz^8Lf*4Ds!6Xc$1Vb&7Mn");
        userLogin.setUserName("sjj-api");
        userLogin.setPlatform(2);
        YmUserDetails yhUserDetails = new YmUserDetails(userLogin);
        String s = JSONObject.toJSONString(userLogin);
        String token = jwtTokenUtil.generateToken(yhUserDetails);
        redisUtil.set(RedisKeyManager.pc_token_key+token, s);
        return tokenHead+token;
    }

    /**
     * 监听 领料出库动作
     */
    @Override
    public void listenerAddOutOrder(List<ListenerOutOrderItemDto> dtos,boolean is_test) {
        ListenerOutOrderItemDto listenerOutOrderItemDto = dtos.get(0);

        String houseName=listenerOutOrderItemDto.getHouseName();

     //
        Date date = new Date();
        String s = DateKit.dateFormat(date, "yyyy-MM-dd");
        if("DKL配件仓".equals(houseName)){
            if(UtilValidate.isNotEmpty(listenerOutOrderItemDto.getSource())&&"提交".equals(listenerOutOrderItemDto.getSource())){
                log.info("--出库 来源是提交 不执行亮灯逻辑："+listenerOutOrderItemDto.getSource());
                return;
            }
            String jsonString =JSONObject.toJSONString(dtos);
            redisUtil.set("outOrder:"+s+":"+date.getTime(),jsonString);
            //匹配一下1区还是2区
            List<BigInteger> location1=new ArrayList<>();
            List<BigInteger> location2=new ArrayList<>();

            for (ListenerOutOrderItemDto dto : dtos) {
                //1区
                String houseLocationTID = dto.getHouseLocationTID();
                if(UtilValidate.isEmpty(houseLocationTID)){
                    //没有库位
                    continue;
                }
                if(dto.getHouseLocationOID().equals(BigInteger.ZERO)){
                    //没有库位
                    continue;
                }
                if(houseLocationTID.contains("配件2区")){
                    location2.add(dto.getHouseLocationOID());
                }else{
                    location1.add(dto.getHouseLocationOID());
                }

            }
            FnMsLocationDto fnMsLocationDto=new FnMsLocationDto();
            fnMsLocationDto.setLocation1(location1);
            fnMsLocationDto.setLocation2(location2);


            batchOnLight(fnMsLocationDto,"outOrder",dtos,null,is_test,true);
        }
    }

    /**
     监听 选中的库存数据
     */
    @Override
    public void listenerClickStockItem(List<ListenerStockItemDto> items,boolean is_test,boolean is_now) {
        String houseName=items.get(0).getHouseName();

        List<BigInteger> houseLocationOIDs=new ArrayList<>();
        for (ListenerStockItemDto dto : items) {
            houseLocationOIDs.add(dto.getHouseLocationOID());
        }
        Date date = new Date();
        String s = DateKit.dateFormat(date, "yyyy-MM-dd");
        if("DKL配件仓".equals(houseName)){
            String jsonString =JSONObject.toJSONString(items);
            redisUtil.set("stock:"+s+":"+date.getTime(),jsonString);
            //匹配一下1区还是2区
            List<BigInteger> location1=new ArrayList<>();
            List<BigInteger> location2=new ArrayList<>();
            for (ListenerStockItemDto dto : items) {

                //1区
                String houseLocationTID = dto.getHouseLocationTID();
                if(UtilValidate.isEmpty(houseLocationTID)){
                    //没有库位
                    continue;
                }
                if(houseLocationTID.contains("配件2区")){
                    location2.add(dto.getHouseLocationOID());
                }else{
                    location1.add(dto.getHouseLocationOID());
                }

            }
            FnMsLocationDto fnMsLocationDto=new FnMsLocationDto();
            fnMsLocationDto.setLocation1(location1);
            fnMsLocationDto.setLocation2(location2);
            batchOnLight(fnMsLocationDto,"stock",null,items,is_test,is_now);
        }

    }


    /**
     *
     * @param fnMsLocationDto
     * @param source
     * @param items1
     * @param items2
     * @param is_test
     * @param is_now 是否马上
     */
    public void batchOnLight(FnMsLocationDto fnMsLocationDto,String source,List<ListenerOutOrderItemDto> items1,List<ListenerStockItemDto> items2,boolean is_test,boolean is_now){
        String jsonString = null;//JSONObject.toJSONString(items)
        if(UtilValidate.isNotEmpty(items1)){
            jsonString =JSONObject.toJSONString(items1);
        }
        if(UtilValidate.isNotEmpty(items2)){
            jsonString =JSONObject.toJSONString(items2);
        }
        log.info("---"+source+"::"+jsonString);
        log.info("--is_test-"+is_test);
        IotMsLog iotMsLog=new IotMsLog();
        iotMsLog.setSource(source);
        iotMsLog.setTxt(jsonString);
        if(!is_test){
            iotMsLog.setIzTest("正式");
        }else{
            iotMsLog.setIzTest("测试");
        }
        iotMsLogService.saveOrUpdate(iotMsLog);

        List<BigInteger> location1 = fnMsLocationDto.getLocation1();
        List<BigInteger> location2 = fnMsLocationDto.getLocation2();
        //库区1
        if(UtilValidate.isNotEmpty(location1)){
            diffKuQuLight(iotMsLog,source,"库区1",location1,is_test);
        }

        //库区2
        if(UtilValidate.isNotEmpty(location2)){
            Thread thread=new Thread(()->{
                try {
                    String msg="";
                    if(source.equals("stock")){
                        log.info("--库区2睡眠2分钟-开始");
                        if(!is_now){
                            Thread.sleep(2 * 60 * 1000);
                        }

                        msg="--库区2睡眠2分钟-结束";
                        log.info(msg);
                    }else{
                        log.info("--库区2睡眠22分钟-开始");
                        if(!is_now){
                            Thread.sleep(22 * 60 * 1000);
                        }
                        msg="--库区2睡眠22分钟-结束";
//                        log.info("--库区2睡眠2分钟-开始");
//                        Thread.sleep(2 * 60 * 1000);
//                        msg="--库区2睡眠2分钟-结束";
                        log.info(msg);
                    }

                    int i = diffKuQuLight(iotMsLog, source, "库区2", location2, is_test);
                  //  EmailUtil.sendEmail("1055162826@qq.com",msg+i, DateKit.getStringNowTime());

                } catch (InterruptedException e) {
                    log.error("库区2延时1分钟后执行异常:"+e.getMessage(),e);
                }
            });
            thread.start();

        }





    }

    /**
     *
     * @param iotMsLog
     * @param source stock,outOrder
     * @param type 库区1，库区2
     */
    public int diffKuQuLight(IotMsLog iotMsLog,String source,String type,List<BigInteger> locationIds,boolean is_test){

        IotTimeLog iotTimeLog=new IotTimeLog();
        iotTimeLog.setSource(source);
        iotTimeLog.setType(type);
        if(!is_test){
            iotTimeLog.setIzTest("正式");
        }else{
            iotTimeLog.setIzTest("测试");
        }
        iotTimeLog.setLogId(iotMsLog.getId());

        IotTagQueryCriteria criteria=new IotTagQueryCriteria();
        criteria.setHouseLocationIdIn(locationIds);


        List<String> list=new ArrayList<>();
        for(BigInteger id: locationIds){
            list.add(id.toString());
        }
        iotTimeLog.setLocationIds(String.join(",",list));

        //普通标签mac地址
        List<IotTag> iotTags = iotTagService.queryAll(criteria);
        List<String> k1_tagMacs=new ArrayList<>();
        List<String> result_tagMacs=new ArrayList<>();
        for (IotTag iotTag : iotTags) {
            k1_tagMacs.add(iotTag.getTagMac());
        }
        //巷道灯标签mac地址
        List<IotTag> xiandaoDengs = iotTagService.findXiandaoDengByTagMacIn(k1_tagMacs);

        List<String> xd_tagMacIn=new ArrayList<>();
        for (IotTag iotTag : xiandaoDengs) {
            xd_tagMacIn.add(iotTag.getTagMac());
        }
        result_tagMacs.addAll(xd_tagMacIn);
        result_tagMacs.addAll(k1_tagMacs);




        //标签灯+巷道灯 一起亮
        Gson gson = new Gson();



        String jsonStr = "";

        String url="/iot/easyfinder/bgTag/lightByLightModeId";

        JSONObject send=new JSONObject();
        send.put("tagMacs",result_tagMacs);
        send.put("lightOff",false);
        send.put("lightModeId","301");

        // 分库区指定网关
        //库区1: 30EB1F5B122C
        //库区2: 30EB1F5E9D98
        if("库区1".equals(type)){
            send.put("gatewayMacList",new String[]{"30EB1F5B122C"});
        }else{
            send.put("gatewayMacList",new String[]{"30EB1F5E9D98"});
        }
        jsonStr= gson.toJson(send);
        log.info("---ms发送亮灯："+url+":参数:"+jsonStr);

        //记录请求参数
        iotTimeLog.setRequestSend(jsonStr);
        //库位标签灯亮起
        JSONObject jsonObject = iotHttpUtil.httpPostStr(url, jsonStr);
        log.info("库位标签灯亮起:"+"source:"+source+jsonObject);
        JSONArray jsonArray1=null;
        int code=jsonObject.getIntValue("code");

        if(200==code){
            try{
              //  jsonArray1 = jsonObject.getJSONArray("data");

                Date now = new Date();
                iotTimeLog.setStartTime(now);
                //记录结束时间
                int df=1;//秒
                if(source.equals("stock")){
                    df=30;//查看库位延时30秒
                }else{
                    /**
                     * 库区1 定时 1800秒 30分钟
                     * 库区2 定时 1200秒 20分钟
                     * 测试 2分钟
                     */
                    if("库区1".equals(type)){
                        df=1200;
                    }else{
                        df=1200;
                    }
//                    df=120;

                }
                Date end_time = DateKit.dateAdd(7, now, df);
                iotTimeLog.setEndTime(end_time);
                iotTimeLog.setResponeSend(jsonObject.getString("data"));

                iotTimeLogService.saveOrUpdate(iotTimeLog);
                //定时器开启
                log.info("--设置定时期 tag_open:"+iotTimeLog.getId());
                redisUtil.set("tag_open:"+iotTimeLog.getId(),iotTimeLog.getId());

                //设置开启状态
                IotTagQueryCriteria c1=new IotTagQueryCriteria();
                c1.setTagMacIn(result_tagMacs);
                c1.setStatus(1);
                iotTagService.batchUpStatus(c1);
//                List<IotTag> iotTags1 = iotTagService.queryAll(c1);
                log.info("---修改亮灯状态:开启"+result_tagMacs);

            } catch (Exception e) {
                log.error("签灯亮起请求异常2："+e.getMessage());
            }
        }else{
            log.error("签灯亮起请求异常1："+jsonObject);
        }
        return code;
    }


    @Override
    public void testAgainOpenByLog(String id) {
        IotMsLog msLog = iotMsLogService.getById(id);
        String source = msLog.getSource();
        String txt = msLog.getTxt();
        if("stock".equals(source)){
            List<ListenerStockItemDto> dtos = JSONArray.parseArray(txt, ListenerStockItemDto.class);
            listenerClickStockItem(dtos,true,true);
        }else{
            List<ListenerOutOrderItemDto> dtos = JSONArray.parseArray(txt, ListenerOutOrderItemDto.class);
            listenerAddOutOrder(dtos,true);
        }

    }



    @Override
    public JSONObject testLight() {
        List<String> tagMacs=new ArrayList<>();
        tagMacs.add("A6C080A21E8B");
        Gson gson = new Gson();
        String jsonStr = gson.toJson(tagMacs);
        JSONObject jsonObject = iotHttpUtil.httpPostStr("/iot/easyfinder/bgTag/light", jsonStr);
        return jsonObject;
    }

    @Override
    public void stockPcLight(List<VckStock> stocks) {
        List<ListenerStockItemDto> list=new ArrayList<>();
        for (VckStock vckStock : stocks) {
            ListenerStockItemDto dto=new ListenerStockItemDto();
            dto.setHouseName(vckStock.getWiname());//仓库名称
            dto.setHouseOID(BigInteger.valueOf(Long.parseLong(vckStock.getWitid())));//仓库id
            dto.setHouseLocationOID(BigInteger.valueOf(Long.parseLong(vckStock.getKuWeiTid())));//库位id
            dto.setHouseLocationTID(vckStock.getKuWei());//库位名称
            dto.setMaterialName(vckStock.getMname());
            dto.setMaterialTID(vckStock.getMtid());
            dto.setOperator(getUserName());
            dto.setOperatingTime(new Timestamp(System.currentTimeMillis()));
            list.add(dto);
        }
        if(list.size()>0){
            listenerClickStockItem(list,true,true);
        }
    }
}
